package com.waikuai.shop.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.waikuai.shop.common.result.Result;
import com.waikuai.shop.dto.ProductDTO;
import com.waikuai.shop.service.ProductService;
import com.waikuai.shop.vo.ProductDetailVO;
import com.waikuai.shop.vo.ProductSimpleVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("/products")
@RequiredArgsConstructor
@Validated
public class ProductController {

    private final ProductService productService;

    @Value("${business.upload.path:/uploads}")
    private String uploadRootPath;

    private Path resolvePhotoDir() throws IOException {
        Path baseDir = Paths.get(uploadRootPath).toAbsolutePath().normalize();
        Path photoDir = baseDir.resolve("photo");
        if (Files.notExists(photoDir)) {
            Files.createDirectories(photoDir);
        }
        return photoDir;
    }

    private String buildPhotoUrl(String filename) {
        return "/api/photo/" + filename;
    }

    @GetMapping
    public Result<IPage<ProductSimpleVO>> getProductPage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "20") Integer size,
            @RequestParam(required = false) Long categoryId,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) Integer status,
            @RequestParam(required = false) Integer isFeatured,
            @RequestParam(required = false) String orderBy,
            @RequestParam(required = false) String orderType) {

        try {
            Page<ProductSimpleVO> page = new Page<>(current, size);
            IPage<ProductSimpleVO> result = productService.getProductPage(page, categoryId, keyword, status, isFeatured, orderBy, orderType);

            log.info("分页查询商品列表成功，页码: {}, 页大小: {}, 总数: {}", current, size, result.getTotal());
            return Result.success("查询商品列表成功", result);
        } catch (Exception e) {
            log.error("分页查询商品列表失败: {}", e.getMessage(), e);
            return Result.error("查询商品列表失败");
        }
    }

    @GetMapping("/{productId}")
    public Result<ProductDetailVO> getProductDetail(@PathVariable Long productId, HttpServletRequest request) {
        try {
            Long userId = getUserIdFromToken(request);
            ProductDetailVO productDetail = productService.getProductDetail(productId, userId);

            if (productDetail == null) {
                return Result.error("商品不存在");
            }

            productService.incrementViewCount(productId);

            log.info("获取商品详情成功，商品ID: {}, 用户ID: {}", productId, userId);
            return Result.success("获取商品详情成功", productDetail);
        } catch (Exception e) {
            log.error("获取商品详情失败，商品ID: {}, 错误: {}", productId, e.getMessage(), e);
            return Result.error("获取商品详情失败");
        }
    }

    @GetMapping("/hot")
    public Result<List<ProductSimpleVO>> getHotProducts(
            @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<ProductSimpleVO> hotProducts = productService.getHotProducts(limit);
            log.info("获取热门商品列表成功，数量: {}", hotProducts.size());
            return Result.success("获取热门商品成功", hotProducts);
        } catch (Exception e) {
            log.error("获取热门商品列表失败: {}", e.getMessage(), e);
            return Result.error("获取热门商品失败");
        }
    }

    @GetMapping("/new")
    public Result<List<ProductSimpleVO>> getNewProducts(
            @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<ProductSimpleVO> newProducts = productService.getNewProducts(limit);
            log.info("获取新品商品列表成功，数量: {}", newProducts.size());
            return Result.success("获取新品商品成功", newProducts);
        } catch (Exception e) {
            log.error("获取新品商品列表失败: {}", e.getMessage(), e);
            return Result.error("获取新品商品失败");
        }
    }

    @GetMapping("/featured")
    public Result<List<ProductSimpleVO>> getFeaturedProducts(
            @RequestParam(defaultValue = "10") Integer limit) {
        try {
            List<ProductSimpleVO> featuredProducts = productService.getFeaturedProducts(limit);
            log.info("获取推荐商品列表成功，数量: {}", featuredProducts.size());
            return Result.success("获取推荐商品成功", featuredProducts);
        } catch (Exception e) {
            log.error("获取推荐商品列表失败: {}", e.getMessage(), e);
            return Result.error("获取推荐商品失败");
        }
    }

    @GetMapping("/category/{categoryId}")
    public Result<List<ProductSimpleVO>> getProductsByCategory(
            @PathVariable Long categoryId,
            @RequestParam(defaultValue = "20") Integer limit) {
        try {
            List<ProductSimpleVO> products = productService.getProductsByCategoryId(categoryId, limit);
            log.info("根据分类获取商品列表成功，分类ID: {}, 数量: {}", categoryId, products.size());
            return Result.success("获取分类商品成功", products);
        } catch (Exception e) {
            log.error("根据分类获取商品列表失败，分类ID: {}, 错误: {}", categoryId, e.getMessage(), e);
            return Result.error("获取分类商品失败");
        }
    }

    @GetMapping("/search")
    public Result<List<ProductSimpleVO>> searchProducts(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "20") Integer limit) {
        try {
            if (keyword.trim().isEmpty()) {
                return Result.error("搜索关键词不能为空");
            }

            List<ProductSimpleVO> searchResults = productService.searchProducts(keyword.trim(), limit);
            log.info("搜索商品成功，关键词: {}, 数量: {}", keyword, searchResults.size());
            return Result.success("搜索商品成功", searchResults);
        } catch (Exception e) {
            log.error("搜索商品失败，关键词: {}, 错误: {}", keyword, e.getMessage(), e);
            return Result.error("搜索商品失败");
        }
    }

    @PostMapping
    public Result<String> createProduct(@Valid @RequestBody ProductDTO productDTO) {
        try {
            boolean result = productService.createProduct(productDTO);
            if (result) {
                log.info("创建商品成功，商品名称: {}", productDTO.getProductName());
                return Result.success("创建商品成功");
            } else {
                return Result.error("创建商品失败");
            }
        } catch (Exception e) {
            log.error("创建商品失败，商品名称: {}, 错误: {}", productDTO.getProductName(), e.getMessage(), e);
            return Result.error("创建商品失败");
        }
    }

    @PutMapping("/{productId}")
    public Result<String> updateProduct(
            @PathVariable Long productId,
            @Valid @RequestBody ProductDTO productDTO) {
        try {
            productDTO.setId(productId);
            boolean result = productService.updateProduct(productDTO);
            if (result) {
                log.info("更新商品成功，商品ID: {}", productId);
                return Result.success("更新商品成功");
            } else {
                return Result.error("更新商品失败");
            }
        } catch (Exception e) {
            log.error("更新商品失败，商品ID: {}, 错误: {}", productId, e.getMessage(), e);
            return Result.error("更新商品失败");
        }
    }

    @DeleteMapping("/{productId}")
    public Result<String> deleteProduct(@PathVariable Long productId) {
        try {
            boolean result = productService.deleteProduct(productId);
            if (result) {
                log.info("删除商品成功，商品ID: {}", productId);
                return Result.success("删除商品成功");
            } else {
                return Result.error("删除商品失败");
            }
        } catch (Exception e) {
            log.error("删除商品失败，商品ID: {}, 错误: {}", productId, e.getMessage(), e);
            return Result.error("删除商品失败");
        }
    }

    @PutMapping("/{productId}/put-on-shelf")
    public Result<String> putOnShelf(@PathVariable Long productId) {
        try {
            boolean result = productService.putOnShelf(productId);
            if (result) {
                log.info("上架商品成功，商品ID: {}", productId);
                return Result.success("上架商品成功");
            } else {
                return Result.error("上架商品失败");
            }
        } catch (Exception e) {
            log.error("上架商品失败，商品ID: {}, 错误: {}", productId, e.getMessage(), e);
            return Result.error("上架商品失败");
        }
    }

    @PutMapping("/{productId}/pull-off-shelf")
    public Result<String> pullOffShelf(@PathVariable Long productId) {
        try {
            boolean result = productService.pullOffShelf(productId);
            if (result) {
                log.info("下架商品成功，商品ID: {}", productId);
                return Result.success("下架商品成功");
            } else {
                return Result.error("下架商品失败");
            }
        } catch (Exception e) {
            log.error("下架商品失败，商品ID: {}, 错误: {}", productId, e.getMessage(), e);
            return Result.error("下架商品失败");
        }
    }

    @PutMapping("/{productId}/featured")
    public Result<String> setFeatured(
            @PathVariable Long productId,
            @RequestParam @NotNull Boolean featured) {
        try {
            boolean result = productService.setFeatured(productId, featured);
            if (result) {
                log.info("设置商品推荐状态成功，商品ID: {}, 推荐状态: {}", productId, featured);
                return Result.success("设置推荐状态成功");
            } else {
                return Result.error("设置推荐状态失败");
            }
        } catch (Exception e) {
            log.error("设置商品推荐状态失败，商品ID: {}, 推荐状态: {}, 错误: {}", productId, featured, e.getMessage(), e);
            return Result.error("设置推荐状态失败");
        }
    }

    @PutMapping("/{productId}/stock")
    public Result<String> updateStock(
            @PathVariable Long productId,
            @RequestParam @NotNull Integer quantity) {
        try {
            boolean result = productService.updateStock(productId, quantity);
            if (result) {
                log.info("更新商品库存成功，商品ID: {}, 变更数量: {}", productId, quantity);
                return Result.success("更新库存成功");
            } else {
                return Result.error("更新库存失败");
            }
        } catch (Exception e) {
            log.error("更新商品库存失败，商品ID: {}, 变更数量: {}, 错误: {}", productId, quantity, e.getMessage(), e);
            return Result.error("更新库存失败");
        }
    }

    /**
     * 上传商品图片
     */
    @PostMapping("/upload-image")
    public Result<String> uploadImage(@RequestParam("file") MultipartFile file) {
        try {
            // 验证文件
            if (file.isEmpty()) {
                return Result.error("上传文件不能为空");
            }

            // 验证文件类型
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                return Result.error("只能上传图片文件");
            }

            // 验证文件大小（限制为5MB）
            if (file.getSize() > 5 * 1024 * 1024) {
                return Result.error("图片大小不能超过5MB");
            }

            // 创建上传目录
            Path uploadPath = resolvePhotoDir();

            // 生成唯一文件名
            String originalFilename = file.getOriginalFilename();
            String extension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }
            String filename = UUID.randomUUID().toString() + extension;

            // 保存文件
            Path filePath = uploadPath.resolve(filename);
            Files.copy(file.getInputStream(), filePath);

            // 生成访问URL（加上/api前缀，与静态资源映射路径一致）
            String imageUrl = buildPhotoUrl(filename);

            log.info("商品图片上传成功，文件名: {}, URL: {}", filename, imageUrl);
            return Result.success("上传成功", imageUrl);

        } catch (IOException e) {
            log.error("商品图片上传失败: {}", e.getMessage(), e);
            return Result.error("图片上传失败：" + e.getMessage());
        } catch (Exception e) {
            log.error("商品图片上传失败: {}", e.getMessage(), e);
            return Result.error("图片上传失败");
        }
    }

    /**
     * 批量上传商品图片
     */
    @PostMapping("/upload-images")
    public Result<List<String>> uploadImages(@RequestParam("files") MultipartFile[] files) {
        try {
            if (files == null || files.length == 0) {
                return Result.error("请选择要上传的图片");
            }

            // 限制一次最多上传10张图片
            if (files.length > 10) {
                return Result.error("一次最多上传10张图片");
            }

            List<String> imageUrls = new ArrayList<>();
            
            // 创建上传目录
            Path uploadPath = resolvePhotoDir();

            for (MultipartFile file : files) {
                // 验证文件
                if (file.isEmpty()) {
                    continue;
                }

                // 验证文件类型
                String contentType = file.getContentType();
                if (contentType == null || !contentType.startsWith("image/")) {
                    log.warn("跳过非图片文件: {}", file.getOriginalFilename());
                    continue;
                }

                // 验证文件大小（限制为5MB）
                if (file.getSize() > 5 * 1024 * 1024) {
                    log.warn("跳过超大文件: {}", file.getOriginalFilename());
                    continue;
                }

                // 生成唯一文件名
                String originalFilename = file.getOriginalFilename();
                String extension = "";
                if (originalFilename != null && originalFilename.contains(".")) {
                    extension = originalFilename.substring(originalFilename.lastIndexOf("."));
                }
                String filename = UUID.randomUUID().toString() + extension;

                // 保存文件
                Path filePath = uploadPath.resolve(filename);
                Files.copy(file.getInputStream(), filePath);

                // 生成访问URL（加上/api前缀，与静态资源映射路径一致）
                String imageUrl = buildPhotoUrl(filename);
                imageUrls.add(imageUrl);
            }

            if (imageUrls.isEmpty()) {
                return Result.error("没有成功上传的图片");
            }

            log.info("批量上传商品图片成功，数量: {}", imageUrls.size());
            return Result.success("上传成功", imageUrls);

        } catch (IOException e) {
            log.error("批量上传商品图片失败: {}", e.getMessage(), e);
            return Result.error("图片上传失败：" + e.getMessage());
        } catch (Exception e) {
            log.error("批量上传商品图片失败: {}", e.getMessage(), e);
            return Result.error("图片上传失败");
        }
    }

    private Long getUserIdFromToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            return 2L;
        }
        return null;
    }
}
